﻿
/*============== simpleIRC - http://matthias.van-eeghem.com/ ==============*
 *                                                                         *
 *  File: Logger.cs                                                      *
 *  Project: IRC.dll                                                     *
 *  Author(s): Matthias Van Eeghem <matthias@van-eeghem.com>               *
 *                                                                         *
 * ========================================================================*
 *                                                                         *
 *  This program is free software: you can redistribute it and/or modify   *
 *  it under the terms of the GNU General Public License as published by   *
 *  the Free Software Foundation, either version 3 of the License, or      *
 *  (at your option) any later version.                                    *
 *                                                                         *
 *  This program is distributed in the hope that it will be useful,        *
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
 *  GNU General Public License for more details.                           *
 *                                                                         *
 *  You should have received a copy of the GNU General Public License      *
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
 *                                                                         *
===========================================================================*/

using System;
using System.IO;

namespace simpleIRC
{
    public class Logger
    {
        /// <summary>
        /// This variable holds the actual logger
        /// </summary>
        private TextWriter FileLogger = null;
        /// <summary>
        /// This variable holds the path of the file that's being written to (example: Logs/irc.gtanet.com/#Matthias.txt)
        /// </summary>
        public string FileName { get; private set; }

        /// <summary>
        /// The constructor of the Logger class checks whether another Logger object already uses a TextWriter to this specific file
        /// if it does, we'll use the same TextWriter. If no other Logger object can be found that also writes to the same file
        /// it will create a new TextWriter object.
        /// </summary>
        /// <param name="directoryName">The directory name of the file, this is the servername</param>
        /// <param name="fileName">The name of the file, this is either a servername, a channel name or user name</param>
        
        public Logger(string directoryName, string fileName)
        {
            // First filter out the invalid 
            foreach (char c in new string(Path.GetInvalidFileNameChars()) + new string(Path.GetInvalidPathChars())) fileName = fileName.Replace(c.ToString(), "");
            foreach (char c in new string(Path.GetInvalidFileNameChars()) + new string(Path.GetInvalidPathChars())) directoryName = directoryName.Replace(c.ToString(), "");

            // Create the server directory if it doesn't exist yet
            if (!Directory.Exists(directoryName)) Directory.CreateDirectory("Logs/" + directoryName);

            // Save the file path
            this.FileName = "Logs/" + directoryName + "/" + fileName + ".txt";

            // Check if another Logger object already uses a TextWriter to this file name
            int Count = Core.LoggerList.Count;

            for (int i = 0; i < Count; i++)
            {
                // Ignore this object 
                if (Core.LoggerList[i] == this) continue;
                // If the FileName's aren't the same, ignore it
                if (Core.LoggerList[i].FileName != this.FileName) continue;

                FileLogger = Core.LoggerList[i].FileLogger;
            }

            // If the FileLogger still is null, it means no other object uses this file, we'll have to create a new object
            if(FileLogger == null)
            {
                // Open the log file for writing
                FileLogger = TextWriter.Synchronized(File.AppendText(FileName));

                Log("Opened log file. (File: " + this.FileName + ")");
            }
        }

        /// <summary>
        /// This method writes a string to the log file
        /// </summary>
        /// <param name="line">The string to write</param>

        public void Log(string line)
        {
            if (FileLogger != null)
            {
                // Get the current date and time
                string CurrentDateAndTime = "[" + DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToLongTimeString() + "]";
                // Now write it
                FileLogger.WriteLine(CurrentDateAndTime + " " + line);
            }
        }

        /// <summary>
        /// This method de-links this logger object from the file it's writing to
        /// </summary>

        public void Remove()
        {
            // We can't close the log file if another object is using this same FileLogger too
            int Count = Core.LoggerList.Count;
            int ObjectsUsingThisLogger = 0;

            // Count all of the Logger objects that log to the same file 
            for (int i = 0; i < Count; i++)
            {
                if (Core.LoggerList[i] == this) continue;
                if (Core.LoggerList[i].FileName != this.FileName) continue;

                ObjectsUsingThisLogger++;
            }

            // It's the only Logger that logs to this file
            if(ObjectsUsingThisLogger == 0)
            {
                Log("Closed log file. (File: " + this.FileName + ")");

                // Remove this object from the LoggerList
                Core.LoggerList.Remove(this);

                // Close and clean up the FileLogger object
                FileLogger.Close();
                FileLogger.Dispose();
            }
            // It's not the last object using it, simply remove this object from the LoggerList
            else Core.LoggerList.Remove(this);
        }
    }
}
